package com.bupt.ilink.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bupt.ilink.entity.User;
import com.bupt.ilink.entity.pojo.TeamFlow.DownloadTeamFlowResult;
import com.bupt.ilink.entity.pojo.TeamFlow.TeamFlowQueryRequest;
import com.bupt.ilink.entity.pojo.TeamFlow.TeamFlowResultWithTags;
import com.bupt.ilink.entity.pojo.TeamFlow.UploadTeamFlowInfo;
import com.bupt.ilink.entity.pojo.store.*;
import com.bupt.ilink.entity.store.StoreFlow;
import com.bupt.ilink.entity.store.Tag;
import com.bupt.ilink.entity.store.TeamFlow;
import com.bupt.ilink.mapper.*;
import com.bupt.ilink.service.TeamFlowService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

@Service
@Transactional
public class TeamFlowServiceImpl implements TeamFlowService {
    @Autowired
    TeamFlowMapper teamFlowMapper;

    @Autowired
    TeamFlowTagMapper teamFlowTagMapper;

    @Autowired
    TagMapper tagMapper;

    @Autowired
    StoreFlowMapper storeFlowMapper;

    @Override
    public UploadFlowResult uploadTeamFlow(UploadTeamFlowInfo teamFlowInfo) {
        teamFlowInfo.selfGenerateMetaData();
        teamFlowMapper.insert(teamFlowInfo);
        for (String tagId : teamFlowInfo.getTags()) {
            teamFlowTagMapper.insertTeamFlowTag(teamFlowInfo.getFlowId(), tagId);

        }
        return new UploadFlowResult(teamFlowInfo.getFlowId());
    }

    @Override
    public UpdateFlowResult updateTeamFlow(UploadTeamFlowInfo teamFlowInfo) {
        teamFlowInfo.selfGenerateMetaData();
        teamFlowMapper.updateById(teamFlowInfo);
        HashSet<String> oldTags =new HashSet<>(teamFlowTagMapper.getTagIdsByFlowId(teamFlowInfo.getFlowId()));
        HashSet<String> newTags = new HashSet<>(teamFlowInfo.getTags());
        HashSet<String> backup = new HashSet<>(newTags);
        newTags.removeAll(oldTags);
        oldTags.removeAll(backup);
        for (String tagId : newTags) {
            teamFlowTagMapper.insertTeamFlowTag(teamFlowInfo.getFlowId(), tagId);
        }
        for (String tagId : oldTags) {
            teamFlowTagMapper.deleteTeamFlowTag(teamFlowInfo.getFlowId(), tagId);
        }
        return new UpdateFlowResult(teamFlowInfo.getFlowId());
    }
    @Override
    public GetTagsResult getTags() {
        List<Tag> tags = tagMapper.selectList(null);
        return new GetTagsResult(tags);
    }

    @Override
    public List<TeamFlowResultWithTags> getFlowsByTeamCondition(TeamFlowQueryRequest query) {
        // 关键词模糊搜索
        QueryWrapper<TeamFlow> queryWrapper = new QueryWrapper<>();
        if (query.getSearch() != null && !query.getSearch().isEmpty()) {
            queryWrapper.lambda().like(TeamFlow::getFlowName, query.getSearch())
                    .or().like(TeamFlow::getUserName, query.getSearch())
                    .or().like(TeamFlow::getDescription, query.getSearch());
        }
        if (query.getTeamId() != null && !query.getTeamId().isEmpty()) {
            queryWrapper.lambda().eq(TeamFlow::getTeamId, query.getTeamId());
        }

        // 查询符合条件的 TeamFlow 列表
        List<TeamFlow> teamFlows = teamFlowMapper.selectList(queryWrapper);
        List<TeamFlowResultWithTags> result = new ArrayList<>();

        // 遍历 teamFlows 并处理每个 flow
        for (TeamFlow flow : teamFlows) {
            QueryWrapper<StoreFlow> storeFlowQuery = new QueryWrapper<>();
            storeFlowQuery.lambda().eq(StoreFlow::getFlowId, flow.getFlowId());
            StoreFlow storeFlow = storeFlowMapper.selectOne(storeFlowQuery);

            if (query.getIsPublic() == null) {
                // 如果 isPublic 为空，返回所有结果
                TeamFlowResultWithTags flowResult = convertToTeamFlowResultWithTags(flow);
                addTagsToFlow(flowResult);
                result.add(flowResult);
            } else if (query.getIsPublic()) {
                // isPublic=true，选出两个表里都有的记录
                if (storeFlow != null) {
                    TeamFlowResultWithTags flowResult = convertToTeamFlowResultWithTags(flow);
                    addTagsToFlow(flowResult);
                    result.add(flowResult);
                }
            } else {
                // isPublic=false，选出只在 TeamFlow 表里的记录
                if (storeFlow == null) {
                    TeamFlowResultWithTags flowResult = convertToTeamFlowResultWithTags(flow);
                    addTagsToFlow(flowResult);
                    result.add(flowResult);
                }
            }
        }

        return result;
    }

    private TeamFlowResultWithTags convertToTeamFlowResultWithTags(TeamFlow flow) {
        TeamFlowResultWithTags result = new TeamFlowResultWithTags();
        result.setFlowId(flow.getFlowId());
        result.setFlowName(flow.getFlowName());
        result.setUserId(flow.getUserId());
        result.setUserName(flow.getUserName());
        result.setDescription(flow.getDescription());
        return result;
    }

    private void addTagsToFlow(TeamFlowResultWithTags flow) {
        List<String> tagIds = teamFlowTagMapper.getTagIdsByFlowId(flow.getFlowId());
        List<Tag> tagList = tagMapper.selectBatchIds(tagIds);
        flow.setTags(tagList);
    }

    @Override
    public DownloadTeamFlowResult downloadFlow(String flowId){
        TeamFlow flow = teamFlowMapper.selectById(flowId);
        return DownloadTeamFlowResult.from(flow);
    }
}
